home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / boot / netBoot.new / sys / commands.c < prev    next >
C/C++ Source or Header  |  1990-12-19  |  37KB  |  1,219 lines

  1.  
  2.  
  3. /*
  4.  * @(#)commands.c 1.1 86/09/27
  5.  * Copyright (c) 1986 by Sun Microsystems, Inc.
  6.  */
  7.  
  8. /*
  9.  * commands.c:  Sun ROM monitor command interpreter and execution.
  10.  */
  11. /*CC*************************************************************************
  12.  *CC*
  13.  *CC* 5-Dec-85  Modified the K2 command to reset all of the devices on the
  14.  *CC*        main CPU board that are not reset by the CPU-RESET command
  15.  *CC*  RJHG     But are normally reset by a watchdog reset according to the
  16.  *CC*        Sun/3 architecture manual rev 2.0
  17.  *CC*        Also reset the Intel/Sun control register which is NOT reset
  18.  *CC*        by the CPU-RESET command.  Apperently only the Intel chips
  19.  *CC*        themselves are reset.
  20.  *CC*
  21.  *CC*        NOTE: The K2 command definition is altered to mean a
  22.  *CC*            SOFTWARE reset of all registers/devices on the MAIN
  23.  *CC*            CPU BOARD that are listed as being reset by the
  24.  *CC*            watchdog or power on reset in the Sun-3 Architecture
  25.  *CC*            manual version 2.0
  26.  *CC*
  27.  *CC*************************************************************************/
  28.  
  29. #include "../sun3/sunmon.h"
  30. #include "../h/globram.h"
  31. #include "../dev/zsreg.h"
  32. #include "../sun3/m68vectors.h"
  33. #include "../h/statreg.h"
  34. #include "../sun3/cpu.addrs.h"
  35. #include "../sun3/cpu.map.h"
  36. #include "../h/buserr.h"
  37. #include "../sun3/cpu.misc.h"
  38. #include "../h/pginit.h"
  39. #include "../h/montrap.h"
  40. #include "../h/led.h"
  41. #include "../h/keyboard.h"
  42. #include "../sun3/memerr.h"
  43. #include "../h/interreg.h"
  44. #include "../h/clock.h"
  45. #include "../dev/saio.h"
  46. #include "../h/enable.h"
  47. #include "../h/eeprom.h"
  48. #include "../diag/diagmenus.h" /* required for struct involving the SCSI */
  49.                  /* logic and reseting it with the K2 cmd  */
  50.  
  51. #include "../dev/if_obie.h"   /* required for struct involving the Intel */
  52.                  /* ethernet logic and reseting it with the */
  53.                  /* K2 cmd                                  */
  54. #ifdef  SIRIUS
  55. #include        "../h/cache.h"
  56. #endif  SIRIUS
  57.  
  58.  
  59. extern unsigned char peekchar(), getone();
  60.  
  61. char menu_msg[] = "\nOptional Menu Tests\r\nType a character within 10 seconds to enter Menu Tests...";
  62. /*
  63.  * Opcode definitions that the monitor occasionally stuffs into memory
  64.  */
  65. #define    OPC_TRAP1    0x4E41        /* trap 1 */
  66.  
  67. int trap();        /* Trap handler for trace and bkpt traps */
  68. int bootreset();    /* Call it (no return) to reset and boot */
  69.  
  70. /*
  71.  * Prints and/or modifies a location.  The address and length (2, 4, or 8
  72.  * hex digits) are arguments.  The result is 1 if the location was modified,
  73.  * 2 if it was not, but a cr was typed, and 0 if anything else was typed.
  74.  */
  75. queryval(adr,len,space)
  76.     register int adr;
  77.     int len, space;
  78. {
  79.     register unsigned char c;
  80.     register unsigned long val;
  81.     register int retval;
  82.  
  83.     while (' ' == (c = peekchar())) getone();
  84.  
  85.     if (ishex(c) < 0) {
  86.         /* No value was supplied.  Read current value, print it, then
  87.            see if s/he wants to modify it. */
  88.         printf(": ");
  89.         switch (len) {            /* Get the value from storage */
  90.         default:val = getsb(adr,space); break;
  91.         case 4: val = getsw(adr,space); break;
  92.         case 8: val = getsl(adr,space); break;
  93.         }
  94.         printhex((int)val,len);
  95.  
  96.         /* Value is printed.  If there's more on the line, and it's
  97.            hex, use it; else if there's nonhex, return for continuation,
  98.            else if there's nothing more on the line, quit. */
  99.         if ('\r' != c) {
  100.             getone();
  101.             while (' ' == (c = peekchar())) getone();
  102.             if (ishex(c) >= 0) goto UseIt;
  103.             putchar ('\n');
  104.             if ('\r' == c)    return 0;    /* Done with command */
  105.             else        return 1;    /* Use rest of line */
  106.         }
  107.  
  108.         printf("? ");    /* No arg supplied; ask for one */
  109.         getline(1);
  110.         c = peekchar();
  111.         /* CR typed here means "don't store, but continue" */
  112.         if (c == '\r')        return 1;    /* cr typed */
  113.         if (ishex(c) < 0)    return 0;/* non-hex, non-cr */
  114.         val = getnum();
  115.         retval = 1;        /* Continue after storing */
  116.     } else {
  117.         /* Value supplied on command line or with prev value --
  118.            use it, and quit if end of line, or continue if more */
  119. UseIt:
  120.         val = getnum();
  121.         printf (" -> ");
  122.         printhex ((int)val, len);
  123.         putchar ('\n');
  124.         while (' ' == (c = peekchar())) getone();
  125.         if (c == '\r')    retval = 0;    /* Quit after storing */
  126.         else        retval = 1;    /* Continue after storing */
  127.     }
  128.  
  129.     switch (len) {        /* Put it back in storage */
  130.         default:    putsb(adr,space,val); break;
  131.         case 4:     putsw(adr,space,val); break;
  132.         case 8:     putsl(adr,space,val); break;
  133.     }
  134. /* try sending back retval for now  MJC */
  135. /*
  136.     return 2;
  137. */
  138.     return(retval);
  139. }
  140.  
  141. /* Register names */
  142. char reg_names[][3]= {
  143.     "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
  144.     "A0", "A1", "A2", "A3", "A4", "A5", "A6", 
  145.     "IS", "MS",        /* Two super stack pointers on '020 */
  146.     "US", "SF", "DF", "VB",
  147.     "CA", "CC",        /* Cache controls on 68020 */
  148.     "CX",            /* Context register */
  149.     "SR", "PC",
  150. };
  151.  
  152. /*
  153.  * Display a register, get new value (if any)
  154.  * If right answer:increment and repeat until last reg
  155.  * Arguments are first reg (&r_d0) and first reg to print.
  156.  */
  157. openreg(rbase, radx)
  158.     long *rbase;
  159.     register long *radx;
  160. {
  161.     register char (*r)[3];
  162.  
  163.     radx += (getnum()&0xF);    /* only use last hex digit */
  164.     r = reg_names + (radx - rbase);
  165.     for(; r < reg_names+(sizeof reg_names/sizeof *reg_names); r++, radx++) {
  166.         printf(r);    
  167.         if (!queryval ((int)radx, 8, FC_SD)) break;
  168.     }
  169. }
  170.  
  171. /* Sets up a break point in address space <space> */
  172. dobreak(space)
  173. int space;
  174. {
  175.     register short *bp= gp->g_breakaddr;
  176.     register short *bpa;
  177.  
  178.     if (bp && (getsw(bp,space) != OPC_TRAP1))
  179.         bp = 0;
  180.  
  181.     if (peekchar() == '\r') {
  182.         printhex ( (int)bp, ADDR_LEN);
  183.         printf (" now.\n");
  184.     } else {
  185.         bpa= (short*)getnum();
  186.         if (bp) {
  187.             /* Restore user's old instruction */
  188.             putsw(bp, space, gp->g_breakval);
  189.             /* Restore supervisor's TRAP #1 routine */
  190.             (void) set_evec (EVEC_TRAP1, gp->g_breakvec);
  191.         }
  192.         if (bpa) {
  193.             /* Save new instruction */
  194.             gp->g_breakval = getsw(bpa, space);
  195.             /* Install bkpt atop new instruction */
  196.             putsw(bpa, space, OPC_TRAP1);
  197.             /* Install new TRAP #1 vector in supervisor space */
  198.             gp->g_breakvec = set_evec (EVEC_TRAP1, trap);
  199.             printf ("Break %x installed\n", gp->g_breakval);
  200.         }
  201.         gp->g_breakaddr = bpa;
  202.  
  203.     };
  204. }
  205. struct pgmapent mainmem_pagemap = {1, PMP_ALL, VPM_MEMORY, 0, 0, 0};
  206.  
  207. /*
  208.  * This mini-monitor does only a few things:
  209.  *    a <dig>        open A regs
  210.  *    b <filename>    bootload file and start it
  211.  *    c [<address>]    continue [at <address>]
  212.  *    d <dig>        open D regs
  213.  *    e <hex number>     open address (as word)
  214.  *    g [<address>]    start (call) [at <address>]
  215.  *    k        reset stack [k1 maps, k2 hard reset]
  216.  *    l <hex number>     open address (as long)
  217.  *    m <hex number>    open segment map
  218.  *    o <hex number>    open address (as byte)
  219.  *    p <hex number>    open page map
  220.  *    r         open PC,SR,SS,US
  221.  *    t [y|n|c cmd]    trace yes, no, or continuous
  222.  *    u [specs]    use different console device[s]
  223.  *    z        set simple breakpoint
  224.  */
  225. monitor(monintstack)
  226.     struct monintstack monintstack;
  227.     /* Note: names beginning r_ are references to monintstack */
  228. {
  229.     register char *i;
  230.         struct pgmapent pg;
  231.     register char c;
  232.     register int goadx, adx;
  233.     int (*calladx)();
  234.         struct m25_scsi_control *scsi_ctl; /* pointer to control register   */
  235.                        /* for SCSI interface        */
  236.                        /* 'm25_scsi_control' is in file */
  237.                        /* diagmenus.h            */
  238.     char translationsave;
  239.     register int space;
  240.     char justtooktrace = 0;
  241.     int cnt, LEN, j, k, l, adx_mod16;
  242.     int unsigned long val, va;
  243.     int change = 0;
  244.     int modified = 0;
  245.  
  246.     /*
  247.      * Default address space for storage-reference commands
  248.      * depends on whether the interrupted program was in supervisor
  249.      * or user state.
  250.      */
  251.     if (r_sr & SR_SUPERVISOR)
  252.         space = FC_SD;        /* supervisor data: FC 5 */
  253.     else
  254.         space = FC_UD;        /* user data: FC 1 */
  255.  
  256.     if (gp->g_keybid == 3 && r_vector == EVEC_RESET) {
  257.         if (EEPROM->ee_diag.eed_keyclick == EED_KEYCLICK)
  258.             sendtokbd(KBD_CMD_CLICK);     /* turn on Keybd click */
  259.         else
  260.             sendtokbd(KBD_CMD_NOCLICK);   /* turn off Keybd click */
  261.     }
  262.  
  263.     switch(r_vector) {        /* what caused entry into monitor? */
  264.  
  265.     case EVEC_TRAPE:    /* "Exit to monitor" trap instruc */
  266.         initgetkey();
  267.         break;
  268.  
  269.     case EVEC_KCMD:        /* "K1" command */
  270.         set_leds(~L_RUNNING);        /* Set LED's to normal state */
  271.         map_mainmem();  /* map in main memory */
  272.         break;        /* Just reenter monitor */
  273.  
  274.     case EVEC_BOOTING:
  275.         /* Call boot routine after setting up maps, etc. */
  276.         set_leds(~L_RUNNING);        /* Set LED's to normal state */
  277. BootHere:
  278.         map_mainmem();    /* map in main memory */
  279.         goadx = boot (gp->g_lineptr);
  280.         if (goadx > 0) {
  281.             r_pc = goadx;       /* Boot was OK, goto loaded code */
  282.             goto ContinueTrace;
  283.         }
  284.         break;        /* Then, or else, fall into monitor */
  285.  
  286.     case EVEC_DOG:
  287.         if (EEPROM->ee_diag.eed_dogaction == EED_DOG_REBOOT)
  288.             k2reset();            /* Do a Power-on-Reset */
  289.  
  290.         printf("\nWatchdog reset!\n");
  291.         set_leds(~L_RUNNING);        /* Set LED's to normal state */
  292.         break;
  293.  
  294.     case EVEC_RESET:
  295.         set_leds(~L_RUNNING);        /* Set LED's to normal state */
  296.  
  297.         printf ("Auto-boot in progress...\n");
  298.         gp->g_lineptr = gp->g_linebuf;    /* Empty argument to boot cmd */
  299.         gp->g_linebuf[0] = 0;
  300.         goto BootHere;        /* Go do the boot */
  301.  
  302.     case EVEC_ABORT:
  303.         initgetkey();
  304.         printf("\nAbort");
  305.         goto PCPrint;
  306.  
  307.     case EVEC_MEMERR:
  308.         printf("\nMEMORY ERROR!  Status %x, DVMA-BIT %x, Context %x,",
  309.             MEMORY_ERR_BASE->mr_er, MEMORY_ERR_BASE->mr_dvma,
  310.             MEMORY_ERR_BASE->mr_cxt);
  311.         va = MEMORY_ERR_BASE->mr_vaddr;
  312.         printf("\n  Vaddr: %x", va);
  313.         printf(", Paddr: "); 
  314.                 printhex(((getpgmap(va) << 13) + (va & 0x1FFF)), 8); 
  315.                 printf(", Type %d", (getpgmap(va) & 0xC000000) >> 26);
  316.         MEMORY_ERR_BASE->mr_dvma = 0;    /* Reset latched interrupt */
  317.  
  318.         set_enable(get_enable() | ENA_NOTBOOT | ENA_SDVMA);
  319.         *INTERRUPT_BASE &= ~IR_ENA_CLK7;
  320.         *INTERRUPT_BASE |=  IR_ENA_CLK7;
  321.         j = CLOCK_BASE->clk_intrreg;
  322.  
  323.                 printf(" at ");
  324.                 printhex( (int)r_pc, ADDR_LEN);
  325.                 if (r_format == fvo_format_sixword) {
  326.                         printf(", Instr=");
  327.                         printhex( (int)r_instr_addr, ADDR_LEN);
  328.                     putchar('\n');
  329.         }
  330.         printf("\n");
  331.         if (gp->g_loop & 0x1 != 0) 
  332.             return;
  333.     case EVEC_TRAP1:
  334.         r_pc -= 2;        /* back up to broken word */
  335.     BreakPrint:
  336.         printf("\nBreak ");
  337.         printhex(gp->g_breakval, 4);   /* Print opcode */
  338.         justtooktrace = 1;    /* Allow quick resume with CR */
  339.         goto PCPrint;
  340.  
  341.     case EVEC_TRACE:
  342.         if (gp->g_breaking) {
  343.             /* this is single step past    broken instruction */
  344.             if (getsw(gp->g_breakaddr, space) == gp->g_breakval) {
  345.                 /* good - not bashed since we set it, so reset it */
  346.             putsw(gp->g_breakaddr, space, OPC_TRAP1);
  347.             }
  348.             if (gp->g_breaking == 1) {
  349.             /* Trace was not previously enabled.  Cancel it and
  350.                resume the breakpointed program. */
  351.             r_sr &= ~SR_TRACE;
  352.             gp->g_breaking = 0;
  353.             /* Fix supervisor trace vec */
  354.             (void) set_evec (EVEC_TRACE, gp->g_breaktrvec);
  355.             return;    /* return to instr after bkpt */
  356.             }
  357.             /* Trace was previously enabled.  Take trace trap now. */
  358.             gp->g_breaking = 0;
  359.         }
  360.         /*
  361.          * OK, we got a trace trap, but not because we just executed
  362.          * the instruction at a breakpoint (and are tracing to put
  363.          * back the breakpoint there).
  364.          *
  365.          * If a breakpoint it set at the next instruction, pretend
  366.          * that's why we got entered.  (Bkpt at loc x takes precedence
  367.          * over trace at loc x.)
  368.          */
  369.         if ((long)gp->g_breakaddr == r_pc) 
  370.             goto BreakPrint;
  371.         r_sr |= SR_TRACE;    /* Assume we wanna keep tracing. */
  372.         /* This causes MOVE-to-SR, RTE, etc, to NOT stop the trace. */
  373.         /* Only a mon command will turn the trace bit off, once set */
  374.         justtooktrace = 1;
  375.         printf ("Trace ");
  376.         printhex (*(short *)r_pc, 4);
  377.         goto PCPrint;
  378.  
  379.     case EVEC_BUSERR:
  380.         if (gp->g_because.be_invalid)         /* Invalid Page */
  381.             printf ("Invalid Page ");
  382.         else if (gp->g_because.be_proterr)      /* Protected Page */
  383.             printf ("Protection ");
  384.         else if (gp->g_because.be_timeout)      /* Timeout Error */
  385.             printf ("Timeout ");
  386.         else if (gp->g_because.be_vmeberr)        /* VMEbus Error */
  387.             printf ("VMEbus ");
  388.         else if (gp->g_because.be_fpaberr)      /* FPA Response Error */
  389.                         printf ("FPA Response ");
  390.                 else if (gp->g_because.be_fpaenerr)     /* FPA Enable Error */
  391.                         printf ("FPA Enable ");
  392.         printf("Bus ");        /* Ensure we note it's a bus err */
  393.         goto AccAddPrint;
  394.  
  395.     case EVEC_ADDERR:
  396.         printf("Address ");
  397. AccAddPrint:
  398.         printf("Error");
  399.         if (r_format == fvo_format_bus20long) printf(", long");
  400.         if (gp->g_bestack.be20_ssw.ssw20_df) {
  401.             printf(":\n  Vaddr: ");
  402.             printhex(gp->g_bestack.be20_data_fault_addr,8);
  403.             printf(", Paddr: ");
  404.             va = gp->g_bestack.be20_data_fault_addr;
  405.                         printhex(((getpgmap(va) << 13) + (va & 0x1FFF)), 8);
  406.             printf(", Type %d", (getpgmap(va) & 0xC000000) >> 26);
  407.             printf(", %s, FC %d, Size %d", 
  408.                 gp->g_bestack.be20_ssw.ssw20_rw? "Read":"Write",
  409.                 gp->g_bestack.be20_ssw.ssw20_fcode,
  410.                 gp->g_bestack.be20_ssw.ssw20_siz?
  411.                     gp->g_bestack.be20_ssw.ssw20_siz: 4);
  412.         } else {
  413.             printf(", PC fetch");
  414.         }
  415. PCPrint:
  416.         printf(" at ");
  417.         printhex( (int)r_pc, ADDR_LEN);
  418.         if (r_format == fvo_format_sixword) {
  419.             printf(", Instr=");
  420.             printhex( (int)r_instr_addr, ADDR_LEN);
  421.         }
  422.         putchar('\n');
  423.         break;
  424.         
  425.     case EVEC_MENU_TSTS:
  426.         set_leds(~L_RUNNING);    /* Set LED's to normal state */
  427.         map_mainmem();  /* map in main memory (i.e., set up the page
  428.                  * map for main menu).
  429.                  */
  430.                 menutests(space);
  431.         break;                
  432.  
  433.     case EVEC_BOOT_EXEC:
  434.         set_leds(~L_RUNNING);    /* Set LED's to normal state */
  435.         printf("%s", menu_msg);
  436.  
  437.         for (j = 0; j < 5; j++) {
  438.             if (mayget() != -1) {
  439.                 menutests(space);
  440.                 goto boot_cont; /* Then, go to monitor */
  441.             }
  442.             DELAY(1000000);
  443.         }
  444.  
  445.         gp->g_lineptr = gp->g_linebuf;
  446.             *gp->g_lineptr++ = 0;
  447.         *gp->g_lineptr++ = 0;
  448.             gp->g_lineptr = gp->g_linebuf;
  449.         bootreset();        /* Boot EEPROM path */
  450. boot_cont:
  451.         break;            /* by passing command line */
  452.  
  453.     default: 
  454.     DeFault:
  455.         printf("\nException %x", r_vector);
  456.         if (r_format != fvo_format_short
  457.          && r_format != fvo_format_sixword)
  458.             printf(" format %x", r_format);
  459.         goto PCPrint;
  460.     }    /* end of switch(r_vector) */
  461.  
  462.     r_highsr = 0;        /* clear extraneous high word */
  463.  
  464. /* The following is temporarily deleted cause stack somehow
  465.    gets screwed up FIXME.  mjc 
  466. */
  467. /*    translationsave = gp->g_translation;
  468.     gp->g_translation = TR_ASCII;
  469. */
  470.  
  471.     if (gp->g_tracecmds) {
  472.         /* Auto-execute a command after a trace trap if no keyin */
  473.         if (r_vector != EVEC_TRACE || mayget() >= 0) {
  474.             gp->g_tracecmds = 0;
  475.         } else {
  476.             gp->g_lineptr = gp->g_tracecmds;
  477.             goto TraceCont;
  478.         }
  479.     }
  480.  
  481.     for (;;) {
  482.         if (gp->g_tracecmds) {
  483.             gp->g_lineptr++;
  484.             if (*gp->g_lineptr) 
  485.                 goto TraceCont;
  486.             if (mayget() < 0) 
  487.                 goto ContinueTrace;
  488.         }
  489.         /* Else get a line of input */
  490.         /* Don't prompt or input line for menu tests or
  491.         /* exec boot */
  492.         if (r_vector != EVEC_MENU_TSTS && 
  493.             r_vector != EVEC_BOOT_EXEC) {
  494.             putchar('>');
  495.             getline(1);
  496.             }
  497.         /* reset r_vector for normal Monitor prompts and input */
  498.         if (r_vector == EVEC_MENU_TSTS ||
  499.             r_vector == EVEC_BOOT_EXEC)
  500.             r_vector = EVEC_RESET;
  501.         if (justtooktrace && peekchar() == '\r') 
  502.             goto ContinueTrace;
  503.  
  504.         justtooktrace = 0;
  505.  
  506. TraceCont:
  507.         while(c= getone())         /* Skip control chars */
  508.             if (c >= '0') 
  509.             break;
  510.  
  511.         skipblanks();    /* remove any spaces before argument */
  512.  
  513.         if (c == '\0') 
  514.             continue;
  515.  
  516.         switch(c&UPCASE) {    /* slight hack, force upper case */
  517.  
  518.         case 'A':    /* open A register */
  519.             openreg(&r_d0, &r_a0);
  520.             goto setcontexts;    /* Might have modified UC/SC */
  521.  
  522.         case 'B':    /* Bootload from net, disk, or whatever */
  523.             gp->g_linebuf[gp->g_linesize] = 0;
  524.             /* If first char is not '!', reset system too */
  525.             if ('!' == peekchar()) {
  526.                 getone();    /* Skip the - */
  527.                 r_pc = boot (gp->g_lineptr);
  528.             } else {
  529.                 bootreset();
  530.                 /*NOTREACHED*/
  531.             }
  532.             break;
  533.  
  534.         case 'C':    /* Continue */
  535.             if(ishex(peekchar()) >= 0) 
  536.                 r_pc = getnum();
  537.         ContinueTrace:
  538.             if ( (long)gp->g_breakaddr == r_pc) {
  539.                 putsw(gp->g_breakaddr, space, gp->g_breakval);
  540.                 gp->g_breaking = 1 + (r_sr & SR_TRACE);
  541.                 gp->g_breaktrvec = set_evec(EVEC_TRACE, trap);
  542.                 r_sr |= SR_TRACE;
  543.             }
  544. /*  deleted for the same reason mentioned above  FIXME  mjc
  545.             gp->g_translation = translationsave;
  546. */
  547.             return;
  548.  
  549.         case 'D':    /* open D register */
  550.             openreg(&r_d0, &r_d0);
  551.             goto setcontexts;    /* Might have modified UC/SC */
  552.  
  553.         case 'E':    /* open memory (short word) */
  554.             for(goadx = getnum(); ;goadx+=2) {
  555.                 printhex(goadx, ADDR_LEN);
  556.                 if (!queryval(goadx,4,space)) break;
  557.             }
  558.             break;
  559.  
  560.         case 'F':    /* Fill address space with pattern */
  561.             skipblanks();    /* to next non-blank */
  562.             j = getnum();
  563.                         skipblanks();    /* to next non-blank */ 
  564.             k = getnum(); 
  565.                         skipblanks();    /* to next non-blank */ 
  566.             l = getnum();
  567.                         skipblanks();    /* to next non-blank */ 
  568.             switch (getone() & UPCASE)
  569.               {
  570.  
  571.                 case 'W':
  572.                 LEN = WORD_LEN;
  573.                 j = j & 0xFFFFFFFE; /* make word address */
  574.                 k = k & 0xFFFFFFFE;
  575.                 break;
  576.  
  577.                 case 'L':
  578.                 LEN = LONG_LEN;
  579.                 j = j & 0xFFFFFFFC; /* make long address */
  580.                 k = k & 0xFFFFFFFC;
  581.                 break;
  582.  
  583.                 case 'B':
  584.                 LEN = BYTE_LEN;
  585.                 break;
  586.  
  587.                 default:
  588.                 LEN = BYTE_LEN;
  589.                 break;
  590.               }
  591.             for (adx = j; adx <= k; adx += (LEN/2))
  592.               {
  593.                 switch (LEN)
  594.                  {
  595.                 case BYTE_LEN:
  596.                   putsb(adx,space,l); break;
  597.                 case WORD_LEN:
  598.                   putsw(adx,space,l); break;
  599.                 case LONG_LEN:
  600.                   putsl(adx,space,l); break;
  601.                  }
  602.               }
  603.             break;
  604.  
  605.         case 'G':    /* Go */
  606.             if (ishex (peekchar()) >= 0)
  607.                 *((long*)&calladx) = getnum();
  608.             else
  609.                 *((long*)&calladx) = r_pc;
  610.             gp->g_linebuf[gp->g_linesize] = 0;
  611.                         skipblanks();    /* to next non-blank */ 
  612.             if ((int) calladx < 8) goto v_command;
  613.             (*calladx)(gp->g_lineptr);
  614.             break;
  615.  
  616.         case 'H':
  617.             help();
  618.             break;
  619. #ifdef  SIRIUS
  620.                 case 'I':
  621.                         for (adx = getnum() + CACHEDOFF; ; adx+= CACHEDINCR) {
  622.                             if (adx < CACHEDOFF ||
  623.                                         (adx >= CACHEDOFF
  624.                                          + CACHE_SIZE)) break;
  625.                                 printf("CacheData ");
  626.                                 printhex(adx,8);
  627.                                 if (!queryval(adx,8,FC_MAP)) break;
  628.                         }
  629.                         break;
  630.                  case 'J':
  631.                         for (adx = getnum() + CACHETOFF; ; adx+= CACHETINCR) {
  632.                             if (adx < CACHETOFF ||
  633.                                         (adx >= CACHETOFF
  634.                                          + CACHE_SIZE)) break;
  635.                                 printf("CacheTags ");
  636.                                 printhex(adx,8);
  637.                                 if (!queryval(adx,8,FC_MAP)) break;
  638.                         }
  639.                         break;
  640.  
  641.                 case 'N':
  642.                                 skipblanks();
  643.                                 switch((c=getone()&UPCASE))
  644.                                 {
  645.                                         case 'I':
  646.                                               printf("Invalidate");
  647.                                                 break;
  648.                                         case 'E':
  649.                                               printf("Enable");
  650.                                                 break;
  651.                                         case 'D':
  652.                                               printf("Disable");
  653.                                                 break;
  654.  
  655.                                         default: break;
  656.                                 }
  657.             printf(" Cache\n"); /* for squeeze  */
  658.                         cache_dei(c);  /* do the action */
  659.                         break;
  660.                 case 'Y':  /* flush */
  661.                         skipblanks();
  662.                         c = getone() & UPCASE;
  663.                         /* now, get num-addr */
  664.                         skipblanks();
  665.                         if( (adx=getnum()) < 0) break ; /* error */
  666.                         /* interpret the previous 'c' */
  667.                                 switch(c) {
  668.                                         case 'C' :
  669.                                                 vac_ctxflush(adx);
  670.                                                 printf("Context");
  671.                                                 break;
  672.                                         case 'S' :
  673.                                         case 'P' :
  674.                                                 if( (goadx=getnum()) < 0) break;                                                if( c == 'S') {
  675.                                                       vac_segflush(adx,goadx);
  676.                                                  printf("Segment");
  677.                                                 }
  678.                                                 else {
  679.                                                       vac_pageflush(adx,goadx);
  680.                                                  printf("Page");
  681.                                                 }
  682.                                                 break;
  683.                                         default:
  684. /*                                         printf("Wrong command %c\n",c); */    
  685.                                                 break;
  686.                                         }
  687.             printf(" flushed\n");
  688.                         break;  /* end 'Y' */
  689. #endif  SIRIUS
  690.  
  691.  
  692.         case 'K':    /* reset monitor */
  693.             switch (getnum()) {
  694.  
  695.             case 0:        /* K0 - Reset instruction only */
  696.                 resetinstr(); 
  697.                 *INTERRUPT_BASE |= IR_ENA_INT + IR_ENA_CLK7;
  698.                 /* Enable NMI */
  699. #ifndef GRUMMAN
  700.                 finit (ax, ay); /* Fix video */
  701. #endif GRUMMAN
  702.                 break;
  703.  
  704.             case 1:        /* K1 - Reset 'most everything */
  705.                 softreset();
  706.                 /*NOTREACHED*/
  707.  
  708.             case 2:        /* K2 - Reset just like power-up */
  709.                 resetinstr();
  710.  
  711. #ifndef    M25 /* this register isn't in the m25 (Sun-3/50) so we don't    */
  712.         /* clear it    if this is a Sun-3/50                */
  713.  
  714.                 ETHER_BASE->obie_noreset = 0; /* reset the  */
  715.                 ETHER_BASE->obie_noloop  = 0; /* Intel/Sun  */
  716.                 ETHER_BASE->obie_ca      = 0; /* ethernet   */
  717.                 ETHER_BASE->obie_ie      = 0; /* control reg*/
  718.  
  719. #endif    M25
  720.                   /* reset the keyboard/mouse uart which is */
  721.                   /* not reset by the CPU-RESET instruction */
  722.                   /* in the k2reset code             */
  723.                 reset_uart(&KEYBMOUSE_BASE[0].zscc_control,1);
  724.                 
  725.                 setfc3(sizeof(u_char),ENABLEREG,0);
  726.                     /* clear SYSTEM enable reg */
  727.  
  728.                 setfc3(sizeof(u_char),UDMAENABLEOFF,0);
  729.                     /* clear USR DVMA enable reg */
  730.  
  731.                 setfc3(sizeof(u_char),DIAGREG,0);
  732.                     /* clear USR DVMA enable reg */
  733.  
  734.                 MEMORY_ERR_BASE->mr_er = 0;
  735.                 
  736.                     /* clear memory error control */
  737.                     /* ECC or PARITY memory       */
  738. #ifdef SIRIUS
  739.                     /* clear ECC Diagnostic reg */
  740. #endif SIRIUS
  741.  
  742. #ifdef    M25
  743.                                 scsi_ctl = (struct m25_scsi_control *) 
  744.                                            ((u_int)SCSI_BASE + 
  745.                                                    M25_SCSI_CONTROL_OFFSET);
  746.                 scsi_ctl->status = 0;
  747.                     /* reset the 2 SCSI interface chips */
  748.                     /* and the control logic        */
  749. #endif    M25
  750.  
  751.                 k2reset();
  752.                                 /*NOTREACHED*/
  753.  
  754.             case 0xB:    /* KB - Print power-up banner only */
  755.                 banner();
  756.                 break;
  757.  
  758.             default: 
  759.                 break;
  760.             }
  761.             break;            
  762.  
  763.         case 'L':    /* open memory (long word) */
  764.             for(goadx = getnum(); ;goadx+=4) {
  765.                 printhex(goadx, ADDR_LEN);
  766.                 if (!queryval(goadx,8,space)) break;
  767.             }
  768.             break;
  769.  
  770.         case 'M':    /* open segment map entry */
  771.             for (goadx = getnum() & (ADRSPC_SIZE-1)
  772.                           & ~(PGSPERSEG*BYTESPERPG-1);
  773.                     goadx < ADRSPC_SIZE;
  774.                     goadx += PGSPERSEG*BYTESPERPG)  {
  775.                 printf("SegMap ");
  776.                 printhex(goadx, ADDR_LEN);
  777.                 if (!queryval((int)SEGMAPADR(goadx),2,FC_MAP))
  778.                     break;
  779.             }
  780.             break;
  781.  
  782.         case 'O':    /* open memory (byte) */
  783.             for(goadx = getnum(); ; ++goadx) {
  784.                 printhex(goadx, ADDR_LEN);
  785.                 if (!queryval(goadx,2,space)) break;
  786.             }
  787.             break;
  788.  
  789.         case 'P':    /* set page map */
  790.             for (goadx = getnum()&(ADRSPC_SIZE-1)&~(BYTESPERPG-1);
  791.                     goadx < ADRSPC_SIZE;
  792.                     goadx += BYTESPERPG) {
  793.                 printf("PageMap ");
  794.                 printhex(goadx, ADDR_LEN);
  795.                 { register segnum_t seggy;
  796.                     seggy = getsegmap(goadx);
  797.                     printf(" [");
  798.                     printhex(seggy,2);
  799.                     putchar(']');
  800.                 }
  801.                 if (!queryval((int)PAGEMAPADR(goadx),8,FC_MAP))
  802.                      break;
  803.             }
  804.             break;
  805.         case 'Q':    /* open EEPROM (byte) */
  806.             modified = 0;
  807.             for (adx = getnum() + (long int )EEPROM_BASE; ; ++adx) {
  808.                 if ((adx < (long int )EEPROM_BASE) || 
  809.                     (adx >= (long int )EEPROM_BASE
  810.                      + EEPROM_SIZE)) break;
  811.                 printf("EEPROM ");
  812.                 printhex(adx,EEPROM_LEN);
  813.                 change = queryval(adx,BYTE_LEN,space);
  814.                 if (!change) 
  815.                     break;
  816.                 if (change == 2)    /* EEPROM modified */
  817.                     modified = 1;
  818.             }
  819.             if (modified)
  820.                 eeprom_update(--adx, space);
  821.             break;
  822.         case 'R':    /* open registers */
  823.             openreg(&r_d0, &r_isp);
  824.         setcontexts:
  825.             setcontext(r_context);    /* Modify context reg if set */
  826.             break;
  827.  
  828.         case 'S':
  829.             if (goadx = getnum()) space = goadx&7;
  830.             else printf ("FC%x space\n", space);
  831.             break;
  832.  
  833.         case 'T':    /* Trace: ty = on; tcxxx = on w/cmd; else off */
  834.             switch (UPCASE & getone()) {
  835.             case 'C':
  836.                 {    /* Turn semis into CR's */
  837.                     register unsigned char *foo;
  838.                     foo = gp->g_lineptr;
  839.                     gp->g_tracecmds = foo;
  840.                     while (*foo) {
  841.                         if (*foo++ == ';')
  842.                             *--foo = '\r';
  843.                     }
  844.                 }
  845.                 goto DoTrace;
  846.             case 'Y':
  847.                 gp->g_tracecmds = 0;
  848.             DoTrace:
  849.                 printf ("Tracing...\n");
  850.                 r_sr |= SR_TRACE;
  851.                 gp->g_tracevec = set_evec(EVEC_TRACE, trap);
  852.                 goto ContinueTrace;
  853.             default:
  854.                 r_sr &= ~SR_TRACE;
  855.                 (void) set_evec(EVEC_TRACE, gp->g_tracevec);
  856.                 printf("Trace Off\n");
  857.             }
  858.             break;
  859.  
  860.         case 'U':    /* Use different console I/O */
  861.             usecmd();
  862.             break;
  863.  
  864.         case 'V':    /* View virtual address space */
  865.                         skipblanks();    /* to next non-blank */ 
  866.            j = getnum() & 0xFFFFFFF0;
  867.                    skipblanks();    /* to next non-blank */ 
  868.            k = getnum() & 0xFFFFFFF0;
  869.                    skipblanks();    /* to next non-blank */ 
  870.            switch (getone() & UPCASE)
  871.              {
  872.             case 'B':    /* View in bytes */
  873.                LEN = BYTE_LEN;
  874.                cnt = 16;
  875.                break;
  876.  
  877.             case 'W':    /* View in words */
  878.                LEN = WORD_LEN;
  879.                cnt = 8;
  880.                break;
  881.  
  882.             case 'L':    /* View in longwords */
  883.                LEN = LONG_LEN;
  884.                cnt = 4;
  885.                break;
  886.  
  887.             default:
  888.                LEN = BYTE_LEN;
  889.                cnt = 16;
  890.                break;
  891.              }
  892.                   for (adx_mod16 = j; adx_mod16 <= k; adx_mod16 += 16)
  893.                 {
  894.                   printhex(adx_mod16,ADDR_LEN);
  895.                   printf(":  ");
  896.                   for (adx = adx_mod16;
  897.                  adx < adx_mod16 + 16; adx += (LEN/2))
  898.                   {
  899.                  switch (LEN)
  900.                   {
  901.                       case BYTE_LEN:    /* display bytes */
  902.                          val = getsb(adx,space); break;
  903.                       case WORD_LEN:    /* display in words */
  904.                          val = getsw(adx,space); break;
  905.                       case LONG_LEN:    /* display in longwords */
  906.                          val = getsl(adx,space); break;
  907.                   }
  908.                  printhex((int)val,LEN);
  909.                       printf(" ");
  910.                   }
  911.                  printf("    ");
  912.                  for (adx=adx_mod16; adx < adx_mod16 + 16;
  913.                      adx += 1)
  914.                     {
  915.                         c = getsb(adx, space) & 0x7F;
  916.                         if ((c > 0x20) && (c < 0x7F))
  917.                     putchar(c);
  918.                         else
  919.                     putchar(0x2E);
  920.                     }
  921.                 printf("\n");
  922.                 l = mayget();
  923.                 if ((l != -1) && (l != ' ')) getchar();
  924.                 if (l == ' ') break;
  925.               }
  926.         break;
  927.  
  928.  
  929.  
  930.         case 'W':    /* Vector */
  931.             *((long*)&calladx) = getnum();
  932.             gp->g_linebuf[gp->g_linesize] = 0;
  933.                         skipblanks();    /* to next non-blank */ 
  934.         v_command:
  935.             (*gp->g_vector_cmd)((long)calladx, gp->g_lineptr);
  936.             break;
  937.  
  938.         case 'X':    /* Extended Tests */
  939.             if (gp->g_insource == INKEYB)
  940.                 gp->g_echoinput = 0x12;
  941.             menureset();
  942.             /* Not reached */
  943.  
  944.         case 'Z':    /* Zap breakpoint in, 0 removes, none shows */
  945.             dobreak(space);
  946.             break;
  947.  
  948.         default:
  949.             printf("What?\n");
  950.             break;
  951.         }    /* end of switch(c&UPCASE) */
  952.     }        /* End of loop forever */
  953. }            /* END of procedure monitor() */
  954.  
  955.  
  956. /*
  957.  * Subroutine callable via ROM Vector Table which will cause the system
  958.  * to reboot using a specified (or defaulted) argument string, as if it
  959.  * had been typed by the user.
  960.  *
  961.  * Just copy the string to linbuf so it won't get trashed, and call
  962.  * bootreset() which will do all the rest.
  963.  */
  964. boot_me(string)
  965.     char *string;
  966. {
  967.  
  968.     gp->g_lineptr = gp->g_linebuf;
  969.     while (*gp->g_lineptr++ = *string++) ;
  970.     gp->g_lineptr = gp->g_linebuf;
  971.     bootreset();    /*NOTREACHED*/
  972. }
  973.     
  974. /*
  975.  * Dummy handler for 'v' (vector) routine
  976.  */
  977. void
  978. vector_default(addr, string)
  979.     char *addr;
  980.     char *string;
  981. {
  982.     /* As a demonstration, use it to print strings. */
  983.     if (*string == '%') 
  984.         printf(string, addr);
  985.     else
  986.         printf("Try again.\n");
  987. }
  988.  
  989. /*
  990.  * Map all of main memory
  991.  */
  992. map_mainmem() {
  993.     register char *i;
  994.         struct pgmapent pg;
  995.  
  996.     pg = mainmem_pagemap;   /* map in main memory */
  997.  
  998.         for (i = (char *)0; i < (char *)MAINMEM_MAP_SIZE; pg.pm_page++) {
  999.             setpgmap(i, pg);
  1000.             i += BYTESPERPG;
  1001.         }
  1002. }
  1003.  
  1004. /*
  1005.  * Update EEPROM write count and checksum
  1006.  */
  1007. eeprom_update(adx, space)
  1008.     register int    *adx;
  1009.     int    space;
  1010. {
  1011.     register unsigned char  sum = 0, checksum;
  1012.     register char   *sum_addr, *count_addr, *eeprom_addr;
  1013.     register char    *start, *end;
  1014.     int    count, i;
  1015.  
  1016. /*
  1017.  *    Decide which EEPROM zone was modified 
  1018.  */
  1019.     if (adx > (int *)&(EEPROM->ee_diag.eed_nu2) && 
  1020.         adx < (int *)&(EEPROM->ee_resv.eev_wrcnt[0])) {
  1021.         start = (char *)&(EEPROM->ee_diag.eed_hwupdate);
  1022.         end = (char *)&(EEPROM->ee_resv.eev_wrcnt[0]);
  1023.         sum_addr = (char *)&(EEPROM->ee_diag.eed_chksum[0]);
  1024.         count_addr = (char *)&(EEPROM->ee_diag.eed_wrcnt[0]);
  1025.     } else if (adx > (int *)&(EEPROM->ee_resv.eev_nu2) && 
  1026.                  adx < (int *)&(EEPROM->ee_rom.eer_wrcnt[0])) { 
  1027.                 start = (char *)&(EEPROM->ee_resv.eev_resv[0]);
  1028.                 end = (char *)&(EEPROM->ee_rom.eer_wrcnt[0]);
  1029.         sum_addr = (char *)&(EEPROM->ee_resv.eev_chksum[0]);
  1030.         count_addr = (char *)&(EEPROM->ee_resv.eev_wrcnt[0]);
  1031.     } else if (adx > (int *)&(EEPROM->ee_rom.eer_nu2) && 
  1032.            adx < (int *)&(EEPROM->ee_soft.ees_wrcnt[0])) {  
  1033.                 start = (char *)&(EEPROM->ee_rom.eer_resv[0]); 
  1034.                 end = (char *)&(EEPROM->ee_soft.ees_wrcnt[0]);
  1035.         sum_addr = (char *)&(EEPROM->ee_rom.eer_chksum[0]);
  1036.         count_addr = (char *)&(EEPROM->ee_rom.eer_wrcnt[0]);
  1037.     } else if (adx > (int *)&(EEPROM->ee_soft.ees_nu2) && 
  1038.            adx < (int *)&(EEPROM->ee_soft.ees_resv[243]) + 1) {  
  1039.                 start = (char *)&(EEPROM->ee_soft.ees_resv[0]); 
  1040.                 end = (char *)&(EEPROM->ee_soft.ees_resv[240]) + 1;
  1041.         sum_addr = (char *)&(EEPROM->ee_soft.ees_chksum[0]);
  1042.         count_addr = (char *)&(EEPROM->ee_soft.ees_wrcnt[0]);
  1043.     } else {
  1044.         return;
  1045.     }
  1046. /*
  1047.  *    Calculate a new checksum for the altered area of the EEPROM
  1048.  */
  1049.     for (eeprom_addr = start; eeprom_addr < end; eeprom_addr++) 
  1050.         sum = sum + getsb(eeprom_addr, space);
  1051.  
  1052.     checksum = 256 - sum;    /* sum of bytes + checksum = 8 bit zero */
  1053.     putsb(sum_addr, space, checksum);  /* Write the checksum */
  1054. /*
  1055.  *    Get the current write count & increment by 1
  1056.  */
  1057.     count = getsb(count_addr++, space) << 8; /* Get the new count */
  1058.         DELAY(10000);                            /* Delay for EEPROM recovery */
  1059.         count += getsb(count_addr--, space, count) + 1; /* Get the new count */
  1060.  
  1061. /*
  1062.  *    Write the updated write count in all 4 locations
  1063.  */
  1064.     for (i = 0; i < 4; i++){
  1065.         putsb(count_addr++, space, count >> 8);/* Write the new count */
  1066.             DELAY(10000);                   /* Delay for EEPROM recovery */
  1067.         putsb(count_addr++, space, count); /* Write the new count */
  1068.         DELAY(10000);                   /* Delay for EEPROM recovery */
  1069.     }
  1070. }
  1071.  
  1072. menutests(space) 
  1073.     int    space;
  1074. {
  1075.     register char    c;
  1076.     int        l;
  1077.  
  1078.     for (;;) {
  1079.         printf("\n\nExtended Test Menu:  (Enter 'q' to return");                        printf(" to Monitor)\n\nCmd -  Test\n\n");
  1080. #ifdef M25
  1081.                 display_opt("ae", "Ethernet");
  1082. #else
  1083.                 display_opt("ie", "Ethernet");
  1084. #endif  M25
  1085.                 display_opt("kb", "Keyboard Input");
  1086.                 display_opt("me", "Memory");
  1087. #ifndef GRUMMAN  
  1088.                 display_opt("mk", "Mouse/Keyboard Ports");
  1089. #endif GRUMMAN
  1090.  
  1091. #ifndef M25
  1092.                 display_opt("mt", "TapeMaster Bootpath");
  1093. #endif  M25
  1094.                 display_opt("rs", "Serial Ports");
  1095.                 display_opt("sd", "SCSI Disk Bootpath");
  1096. #ifdef  M25
  1097.                 display_opt("si", "SCSI Interface");
  1098. #endif  M25
  1099.                 display_opt("st", "SCSI Tape Bootpath");
  1100. #ifdef PRISM
  1101.                 display_opt("vm", "Video (Monochrome)");
  1102.                 display_opt("vc", "Video (Color)");
  1103.                 display_opt("ve", "Video Enable Plane");
  1104.                 display_opt("cm", "Color Map");
  1105. #else PRISM
  1106. #ifndef GRUMMAN
  1107.                 display_opt("vi", "Video");
  1108. #endif GRUMMAN
  1109. #endif PRISM
  1110.  
  1111. #ifndef M25
  1112. /*              display_opt("xd", "Xylogics 751 Disk Bootpath");  */
  1113.                 display_opt("xt", "Xylogics Tape Bootpath");
  1114.                 display_opt("xy", "Xylogics 450/451 Disk Bootpath");
  1115. #endif  M25
  1116.                 if ((c = get_cmd()) == 'Q')
  1117.                         break;
  1118.                 l = (int) c;
  1119.                 c = getone() & UPCASE;
  1120.                 l = (l<<8) + (int) c;
  1121.         
  1122.                 switch (l) {
  1123.  
  1124. #ifdef  M25
  1125.                 case(int)'EA':  /* AMD Ethernet test */
  1126.                     amd_ether_test();     /* execute ethernet test */
  1127.                     break;
  1128. #endif  M25
  1129. #ifndef M25
  1130.                 case (int)'EI': /* Ethernet test */
  1131.                     ether_test(); /* execute ethernet test */
  1132.                     break;
  1133. #endif  M25
  1134.                                 /*
  1135.                                  * The parameter used in call to keybd_test
  1136.                                  * is useless.  keybd_test() doesn't declare
  1137.                                  * any passed parameters, so it's just ignored.
  1138.                                  * keybd_test just checks gp->g_insource to
  1139.                                  * see which device (keyboard or port A or B)
  1140.                                  * to test.
  1141.                                  */
  1142.                 case (int)'BK': /* Keyboard test */
  1143.                     keybd_test(gp->g_insource);
  1144.                       break; 
  1145.  
  1146. #ifndef GRUMMAN  
  1147.                 case (int)'KM': /* Mouse\Keyboard Loopback */
  1148.                       ports_test(1);
  1149.                       break;
  1150. #endif GRUMMAN
  1151.                 case (int)'EM': /* Memory Tests */
  1152.                       memory_test(space, 0);
  1153.                       break;
  1154.  
  1155.                 case (int)'SR': /* Serial Ports test */
  1156.                         ports_test(0);
  1157.                         break;
  1158.  
  1159.                 case (int)'DS': /* SCSI disk bootpath test */
  1160.                         boot_test("sd()");
  1161.                         break;
  1162. #ifdef  M25
  1163.                 case (int)'IS': /* SCSI interface test */
  1164.                         scsi_test();
  1165.                         break;
  1166. #endif  M25
  1167.                 case (int)'TS': /* SCSI tape bootpath test */
  1168.                         boot_test("st()");
  1169.                         break;
  1170. #ifndef M25
  1171.                 case (int)'TM': /* Tape Master bootpath test */
  1172.                         boot_test("mt()");
  1173.                         break;
  1174. #endif  M25
  1175. #ifdef PRISM
  1176.                 case (int)'MV': /* monochrome video test */
  1177.                         memory_test(space, 1);
  1178.                         break;
  1179.  
  1180.                 case (int)'EV': /* enable plane test */
  1181.                         memory_test(space, 2);
  1182.                         break;
  1183.         
  1184.                 case (int)'CV': /* color frame buffer test */
  1185.                         memory_test(space, 3);
  1186.                         break;
  1187.  
  1188.                 case (int)'MC': /* color map test */
  1189.                         memory_test(space, 4);
  1190.                         break;
  1191.  
  1192. #else PRISM
  1193. #ifndef GRUMMAN
  1194.                 case (int)'IV': /* Video test */
  1195.                         memory_test(space, 1); /* execute video test */
  1196.                         break;
  1197. #endif GRUMMAN
  1198. #endif PRISM
  1199. #ifndef M25
  1200.                 case (int)'DX': /* Xylogics 751 disk bootpath test */
  1201.                         boot_test("xd()");
  1202.                         break;
  1203.  
  1204.                 case (int)'TX': /* Xylogics tape bootpath test */
  1205.                         boot_test("xt()");
  1206.                         break;
  1207.  
  1208.                 case (int)'YX': /* Xylogics 450/451 disk bootpath test*/                              boot_test("xy()");
  1209.                         break;
  1210. #endif  M25
  1211.                 default:        /* none of above */
  1212.                         printf("\nInvalid command!\n");
  1213.                         break;
  1214.  
  1215.                 }               /* end of switch */
  1216.     }                     /* end of for loop */
  1217. }
  1218.  
  1219.